package com.lib.core.view.banner;


import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.bumptech.glide.Glide;
import com.lib.core.R;
import com.lib.core.utils.DisplayUtil;
import com.lib.core.view.RoundImageView;

import java.util.ArrayList;
import java.util.List;

public class BannerView<T extends BannerBaseBean> extends FrameLayout {

    public static final int SCROLL_SPEED = 4000;

    private ViewPager vpBanner;

    private List<T> bannerData;

    public List<T> getBannerData() {
        return bannerData;
    }

    private List<ImageView> imageViewList;

    private int bannerCount = 0;

    private Handler handler = new Handler();
    private OnClickedBannerListener<T> listener;

    private boolean autoScroll = true;
    private ViewGroup vpIndicator;
    private List<View> indicatorList;


    public BannerView(Context context) {
        super(context);
        init();
    }

    public BannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    protected void init() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_banner_view, this);
        vpBanner = view.findViewById(R.id.vp_banner);
        vpBanner.setPageMargin(20);
        vpIndicator = view.findViewById(R.id.vp_indicator);
    }

    public void setAutoScroll(boolean autoScroll) {
        this.autoScroll = autoScroll;
    }

    public void setData(List<T> bannerData) {
        vpBanner.removeAllViews();
        this.bannerData = bannerData;
        vpIndicator.removeAllViews();
        if (bannerData.size() <= 0) return;
        initViews();
        initViewPager();
    }

    public void setOnClickedBannerListener(OnClickedBannerListener<T> listener) {
        this.listener = listener;
    }

    /**
     * 根据广告数量初始化图片以及小圆点
     */
    private void initViews() {
        bannerCount = bannerData.size();
        imageViewList = new ArrayList<>();

        for (int i = 0; i < bannerCount; i++) {
            RoundImageView imageView = new RoundImageView(getContext());
            T item = bannerData.get(i);
            final String picUrl = item.getImageUrl();
            int finalI = i;
            imageView.setOnClickListener(v -> {
                if (listener != null) listener.onClicked((ImageView) v, item, finalI);
            });
            Glide.with(getContext()).load(picUrl)
                    .skipMemoryCache(true).into(imageView);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setCornerRadius(5);
            imageView.setType(RoundImageView.TYPE_ROUND);
            imageViewList.add(imageView);
        }
        indicatorList = new ArrayList<>();
        for (int i = 0; i < bannerCount; i++) {
            View view = buildChildView();
            vpIndicator.addView(view);
            indicatorList.add(view);
        }
    }

    /**
     * 初始化ViewPager
     */
    private void initViewPager() {
        vpBanner.setAdapter(new BannerAdapter());
        vpBanner.addOnPageChangeListener(new RecommendAdPageChangedListener());
        vpBanner.setCurrentItem(0);
        indicatorList.get(0).setBackgroundResource(R.drawable.banner_dot_select);
        if (autoScroll) handler.postDelayed(runnable, SCROLL_SPEED);
    }

    /**
     * 生成小圆点
     */
    private View buildChildView() {
        View view = new View(getContext());
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(DisplayUtil.dip2px(getContext(), 7), DisplayUtil.dip2px(getContext(), 7));
        view.setBackgroundResource(R.drawable.selector_banner_indicator);
        lp.setMargins(DisplayUtil.dip2px(
                getContext(), 5), 0, DisplayUtil.dip2px(getContext(), 5), 0);
        view.setLayoutParams(lp);
        return view;
    }

    class RecommendAdPageChangedListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageSelected(int arg0) {
            if (autoScroll) handler.removeCallbacks(runnable);
            int position = arg0 % bannerCount;
            for (int i = 0; i < bannerCount; i++) {
                indicatorList.get(i).setBackgroundResource(R.drawable.selector_banner_indicator);
                indicatorList.get(i).setSelected(position == i);
            }
            if (autoScroll) handler.postDelayed(runnable, SCROLL_SPEED);
        }
    }

    /**
     * 用于自动轮播的线程体
     */
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            int current = vpBanner.getCurrentItem();
            vpBanner.setCurrentItem(current + 1);
        }
    };

    /**
     * 用于存储当页面被添加或删除时的position 当页面个数为3的时候, 无限轮播会出现bug,
     * 必须在destroyItem中判断 当Math.abs(add - remove) == 0的时候不删除页面, 不然会出现空页面的情况.
     */
    private int add = 0;

    class BannerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return bannerCount < 3 ? bannerCount : Integer.MAX_VALUE;
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            int i = position % bannerCount;
            add = i;
            if (imageViewList.get(i).getParent() != null) {
                ((ViewPager) imageViewList.get(i).getParent()).removeView(imageViewList.get(i));
            }
            container.addView(imageViewList.get(i));
            return imageViewList.get(i);
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object arg2) {
            int i = position % bannerCount;
            if (bannerCount == 3 && Math.abs(add - i) == 0)
                return;
            container.removeView(imageViewList.get(i));
        }

        @Override
        public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
            return arg0 == arg1;
        }

    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (autoScroll) handler.postDelayed(runnable, SCROLL_SPEED);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (autoScroll) handler.removeCallbacks(runnable);
    }


    public interface OnClickedBannerListener<T> {
        void onClicked(ImageView view, T item, int position);
    }
}
